"""
研究功能路由
提供研究系统的RESTful API接口
"""

from typing import Optional, AsyncGenerator, List
import uuid
from fastapi import APIRouter, Depends, HTTPException, status, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session

from src.config.database import get_db
from src.models.session import SessionCreate, SessionUpdate, SessionResponse
from src.models.scheduled_task import ScheduledTaskCreate, ScheduledTaskUpdate, ScheduledTaskResponse
from src.services.research_service import ResearchService, research_service
from src.services.auth_service import get_current_user_dep
from src.models.user import User
from src.services.database_session_service import DatabaseSessionService
from src.utils.logging import get_logger
from src.utils.error_handler import api_error_handler
from src.exceptions import ResearchException, SessionNotFoundError
from src.research_core.workflow_manager import workflow_manager

logger = get_logger(__name__)

router = APIRouter(prefix="/research", tags=["research"])

# 初始化服务
research_service = ResearchService()

class ResearchRequest(BaseModel):
    """研究请求模型"""
    question: str
    workflow_type: Optional[str] = None  # 使用当前工作流，如果未指定

class WorkflowInfo(BaseModel):
    """工作流信息模型"""
    name: str
    display_name: str
    description: str

class SwitchWorkflowRequest(BaseModel):
    """切换工作流请求模型"""
    workflow_name: str

class ResearchResponse(BaseModel):
    """研究响应模型"""
    session_id: str
    result: str


@router.get("/workflows", response_model=List[WorkflowInfo])
async def list_workflows():
    """
    获取所有可用工作流列表
    
    Returns:
        工作流信息列表
    """
    try:
        workflows = []
        for name, info in workflow_manager.list_available_workflows().items():
            workflows.append(WorkflowInfo(
                name=name,
                display_name=info["display_name"],
                description=info["description"]
            ))
        return workflows
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取工作流列表失败: {str(e)}")

@router.get("/workflows/current")
async def get_current_workflow():
    """
    获取当前使用的工作流信息
    
    Returns:
        当前工作流信息
    """
    try:
        current_name = workflow_manager.get_current_workflow_name()
        workflows = workflow_manager.list_available_workflows()
        return {
            "current_workflow": current_name,
            "workflow_info": workflows.get(current_name, {})
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取当前工作流失败: {str(e)}")

@router.post("/workflows/switch")
async def switch_workflow(request: SwitchWorkflowRequest):
    """
    切换当前工作流
    
    Args:
        request: 切换工作流请求
        
    Returns:
        切换结果消息
    """
    try:
        workflow_manager.switch_workflow(request.workflow_name)
        return {"message": f"已切换到工作流: {request.workflow_name}"}
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"切换工作流失败: {str(e)}")

@router.post("/query", response_model=ResearchResponse)
async def research_query(
    request: ResearchRequest,
    current_user: User = Depends(get_current_user_dep)
):
    """
    执行研究查询
    
    Args:
        request: 研究请求
        current_user: 当前用户
        
    Returns:
        研究结果
    """
    try:
        session_id = str(uuid.uuid4())
        
        # 确定使用的工作流类型
        workflow_type = request.workflow_type or workflow_manager.get_current_workflow_name()
        
        # 收集所有流式响应
        final_result = ""
        async for chunk in research_service.research(
            question=request.question,
            session_id=session_id,
            workflow_type=workflow_type
        ):
            if chunk["type"] == "final_answer":
                final_result = chunk["content"]
                break
            elif chunk["type"] == "error":
                raise HTTPException(status_code=500, detail=chunk["content"])
        
        if not final_result:
            raise HTTPException(status_code=500, detail="未能生成研究结果")
            
        return ResearchResponse(
            session_id=session_id,
            result=final_result
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/stream")
async def research_stream(
    request: ResearchRequest,
    current_user: User = Depends(get_current_user_dep)
):
    """
    流式执行研究查询
    
    Args:
        request: 研究请求
        current_user: 当前用户
        
    Returns:
        流式研究结果
    """
    from fastapi.responses import StreamingResponse
    
    session_id = str(uuid.uuid4())
    
    # 确定使用的工作流类型
    workflow_type = request.workflow_type or workflow_manager.get_current_workflow_name()
    
    async def event_generator() -> AsyncGenerator[str, None]:
        try:
            async for content in research_service.stream_research(
                question=request.question,
                session_id=session_id,
                workflow_type=workflow_type
            ):
                yield content
        except Exception as e:
            yield f"data: {{\"error\": \"{str(e)}\"}}\n\n"
    
    return StreamingResponse(event_generator(), media_type="text/plain")


@router.get("/sessions/{session_id}", response_model=SessionResponse)
async def get_research_session(
    session_id: str,
    db: Session = Depends(get_db)
):
    """获取研究会话详情"""
    try:
        session = session_service.get_session(db, session_id)
        if not session:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="会话不存在"
            )
        return SessionResponse.from_orm(session)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取研究会话失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取研究会话失败"
        )


@router.put("/sessions/{session_id}", response_model=SessionResponse)
async def update_research_session(
    session_id: str,
    session_data: SessionUpdate,
    db: Session = Depends(get_db)
):
    """更新研究会话"""
    try:
        session = session_service.get_session(db, session_id)
        if not session:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="会话不存在"
            )
        
        updated_session = session_service.update_session(
            db, session_id, session_data
        )
        if not updated_session:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="更新会话失败"
            )
        
        return SessionResponse.from_orm(updated_session)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新研究会话失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新研究会话失败"
        )


@router.delete("/sessions/{session_id}")
async def delete_research_session(
    session_id: str,
    db: Session = Depends(get_db)
):
    """删除研究会话"""
    try:
        db_session_service = DatabaseSessionService(db)
        session = db_session_service.get_session(session_id)
        if not session:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="会话不存在"
            )
        
        success = db_session_service.delete_session(session_id)
        if not success:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="删除会话失败"
            )
        
        return {"message": "会话删除成功"}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除研究会话失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除研究会话失败"
        )
